#include "Mapper.h"
#include "CPUOpCodes.h"
// Mapper subject type, 8 files
#include "MapperNROM.h"
#include "MapperCNROM.h"
#include "MapperAxROM.h"
#include "MapperGxROM.h"
#include "MapperSxROM.h"
#include "MapperColorDreams.h"
#include "MapperGxROM.h"
#include "MapperMMC3.h"
#include "MapperUxROM.h"

PNE_NAMESPACE_BEGIN

NameTableMirroring Mapper::GetNameTableMirroring()
{
    return static_cast<PROJECT_NAME::NameTableMirroring>(m_cartridge.GetNameTableMirroring());
}

std::unique_ptr<Mapper>
Mapper::CreateMapper(
    Mapper::Type mapper_type,
    PROJECT_NAME::Cartridge &cart,
    std::function<void()> interrupt_callback,
    std::function<void(void)> mirroring_callback)
{
    std::unique_ptr<Mapper> ret(nullptr);

    switch (mapper_type)
    {
    case Mapper::Type::NROM:
        ret.reset(new MapperNROM(cart));
        break;
    case Mapper::Type::SxROM:
        ret.reset(new MapperSxROM(cart, mirroring_callback));
        break;
    case Mapper::Type::UxROM:
        ret.reset(new MapperUxROM(cart));
        break;
    case Mapper::Type::CNROM:
        ret.reset(new MapperCNROM(cart));
        break;
    case Mapper::Type::MMC3:
        ret.reset(new MapperMMC3(cart, interrupt_callback, mirroring_callback));
        break;
    case Mapper::Type::AxROM:
        ret.reset(new MapperAxROM(cart, mirroring_callback));
        break;
    case Mapper::Type::ColorDreams:
        ret.reset(new MapperColorDreams(cart, mirroring_callback));
        break;
    case Mapper::Type::GxROM:
        ret.reset(new MapperGxROM(cart, mirroring_callback));
        break;

    default:
        break;
    }

    return ret;
}

PNE_NAMESPACE_END
// DONE